package com.example.teesystem.controller;

import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.metadata.Sheet;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.example.teesystem.common.Permission.PermissionCheck;
import com.example.teesystem.common.cache.IssueCache;
import com.example.teesystem.common.exception.CustomException;
import com.example.teesystem.common.utils.*;
import com.example.teesystem.entity.Course;
import com.example.teesystem.entity.vo.issue.*;
import com.example.teesystem.filter.MyHandlerInterceptor;
import com.example.teesystem.mapper.CourseMapper;
import com.example.teesystem.service.IssueService;
import lombok.Cleanup;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Map;

import static com.example.teesystem.common.utils.FileUtil.SUFFIX;

/**
 * @author : NieYaShi
 * @version : v1.0
 * @createTime : 2022/3/28 10:33
 */
@RestController
@RequestMapping(value = "/tee/issue" , produces = "application/json; charset=utf-8" )
@RequiredArgsConstructor
public class IssueController {
    private final IssueService issueService;
    private final HttpServletResponse response;
    private final CourseMapper courseMapper;

    private final static String EXCEL_MODEL = "/file/excel.xlsx";

    /**
     * 添加单个题目
     * @param issueInsertVo
     * @return
     */
    @PostMapping(value = "/addSingleIssue")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response addSingleIssue(@Valid @RequestBody(required = false) IssueInsertVo issueInsertVo){
        if(issueInsertVo.getType() == IssueUtil.SINGLE_CHOICE || issueInsertVo.getType() == IssueUtil.MULTIPLE_CHOICE || issueInsertVo.getType() == IssueUtil.JUDGE){
            if(issueInsertVo.getSelectionAnswer() == null || issueInsertVo.getSelectionAnswer().length == 0){
                return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
            }
            StringBuilder answer = new StringBuilder();
            for(int i = 0; i < issueInsertVo.getSelectionAnswer().length; i++ ){
                answer.append(issueInsertVo.getSelectionAnswer()[i]).append("$");
            }
            answer.deleteCharAt(answer.lastIndexOf("$"));
            issueInsertVo.setAnswer(answer.toString());
        }else {
            if(issueInsertVo.getAnswer() == null || issueInsertVo.getAnswer().equals("")){
                return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
            }
        }
        return issueService.addSingleIssue(issueInsertVo);
    }

    /**
     * 题目引用
     * @param map
     * @return
     */
    @PostMapping(value = "/bringInIssues")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response bringInIssues(@RequestBody Map<String, String> map){
        String ids = map.get("ids");
        int courseId,type;
        try{
            courseId = Integer.parseInt(map.get("courseId"));
            type = Integer.parseInt(map.get("type"));
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE,courseId)) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }

        return issueService.bringInIssue(ids, courseId,type);
    }

    /**
     * 题目文件上传
     * @param files
     * @param courseId
     * @return
     */
    @PostMapping(value = "/uploadFile")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response uploadFile(@RequestParam("file") MultipartFile[] files,@RequestParam("courseId") int courseId) {
        int id;
        try{
            id = courseId;
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE,id)) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        Course course = courseMapper.selectById(id);
        if(course == null){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        boolean contain = false;
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            String suffixName = fileName.substring(fileName.lastIndexOf("."));
            for (String suffix : SUFFIX) {
                if (suffix.equals(suffixName)) {
                    contain = true;
                    break;
                }
            }
            if (!contain) {
                throw new CustomException(ResultCode.FILE_ERROR);
            }
        }
        return FileUtil.UploadFile(files,FileUtil.FILE_PATH+FileUtil.ISSUE+courseId+"/");
    }

    /**
     * 题目文件下载
     * @param map
     * @return
     */
    @PostMapping(value = "/downloadFile")
    public Response downloadFile(@RequestBody Map<String, String> map) {
        String fileUrl = map.get("fileUrl");
        return FileUtil.DownLoadFile(fileUrl,response);
    }

    /**
     * 题目excel导入
     * @param file
     * @param courseId
     * @return
     */
    @PostMapping(value = "/importIssue")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response importIssue(@RequestParam("file") MultipartFile file, @NotNull @RequestParam("courseId") int courseId,@NotNull @RequestParam("chapterId") int chapterId){
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE,courseId)) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        return issueService.importIssue(file,courseId,chapterId);
    }

    /**
     * 题目更新
     * @param issueUpdateVo
     * @return
     */
    @PostMapping(value = "/updateIssue")
    public Response updateIssue(@Valid @RequestBody IssueUpdateVo issueUpdateVo){
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE, IssueCache.issueMap.get(issueUpdateVo.getId()))) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        return issueService.updateIssue(issueUpdateVo);
    }

    /**
     * 题目删除
     * @param map
     * @return
     */
    @PostMapping(value = "/deleteIssue")
    public Response deleteIssue(@RequestBody Map<String,String> map){
        int id;
        try{
            id = Integer.parseInt(map.get("id"));
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE, IssueCache.issueMap.get(id))) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        return issueService.deleteIssue(id);
    }

    /**
     * 题目excel导出
     * @param response
     * @param map
     * @return
     */
    @RequestMapping(value = "/outPutIssue")
    public Response outPutIssue(HttpServletResponse response,@RequestBody Map<String,String> map){
        String ids = map.get("ids");
        int courseId ;
        try{
            courseId = Integer.parseInt(map.get("courseId"));
        }catch (Exception e){
            return Response.error(ResultCode.PARAMETER_MISS.getMsg(), ResultCode.PARAMETER_MISS.getCode());
        }
        if(!PermissionUtil.permissionCheck(MyHandlerInterceptor.getUid(),PermissionUtil.ISSUE_MANAGE, courseId)) {
            return Response.error(ResultCode.NO_PERMISSION.getMsg(), ResultCode.NO_PERMISSION.getCode());
        }
        List<IssueExcel> issueExcelList = issueService.outPutIssue(ids,courseId);
        try{
            @Cleanup
            ServletOutputStream out = response.getOutputStream();
            ExcelWriter writer = new ExcelWriter(out, ExcelTypeEnum.XLSX, true);
            String fileName = "issueExcel_"+courseId+"_"+ TimeUtil.getSecondTimestamp();
            Sheet sheet = new Sheet(1, 0,IssueExcel.class);
            //设置自适应宽度
            sheet.setAutoWidth(Boolean.TRUE);
            // 第一个 sheet 名称
            sheet.setSheetName("sheet1");
            writer.write(issueExcelList, sheet);
            //通知浏览器以附件的形式下载处理，设置返回头要注意文件名有中文
            response.setHeader("Content-disposition", "attachment;filename=" + new String( fileName.getBytes("gb2312"), "ISO8859-1" ) + ".xlsx");
            writer.finish();
            response.setContentType("multipart/form-data");
            response.setCharacterEncoding("utf-8");
            out.flush();
        }catch (Exception e){
            System.out.println(e.getMessage());
            return Response.error(ResultCode.File_OUTPUT_FAILURE.getMsg(), ResultCode.File_OUTPUT_FAILURE.getCode());
        }
        return Response.ok();
    }

    /**
     * 分页查询所有题目（指定课程、题库）
     * @param issueSelectVo
     * @return
     */
    @PostMapping(value = "/getIssueByCourseId")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response getIssueByCourseId(@Valid @RequestBody IssueSelectVo issueSelectVo){
        return issueService.getIssueByMultiCondition(issueSelectVo);
    }

    /**
     * 添加多个条件查询
     * @param issueSelectVo
     * @return
     */
    @PostMapping(value = "/getIssueByMultiCondition")
    @PermissionCheck(PermissionUtil.ISSUE_MANAGE)
    public Response getIssueByMultiCondition(@Valid @RequestBody IssueSelectVo issueSelectVo){
        return issueService.getIssueByMultiCondition(issueSelectVo);
    }

    /**
     * 获取题目详情
     * @param map
     * @return
     */
    @PostMapping(value = "/getIssueMessage")
    public Response getIssueMessage(@RequestBody Map<String, String> map){
        int id = Integer.parseInt(map.get("id"));
        try {
            return issueService.getIssueMsg(id);
        }catch (Exception e){
            return Response.error(ResultCode.GET_ERROR.getMsg(), ResultCode.GET_ERROR.getCode());
        }
    }

    /**
     * 题库可视化题目类型及其数量
     * @param issueVisibilityVo
     * @return
     */
    @PostMapping(value = "/getTypeVisibility")
    public Response getTypeVisibility(@RequestBody @Valid IssueVisibilityVo issueVisibilityVo){
        return issueService.getTypeVisibility(issueVisibilityVo);
    }

    /**
     * 题库可视化题目难度及其数量
     * @param issueVisibilityVo
     * @return
     */
    @PostMapping(value = "/getDifficultyVisibility")
    public Response getDifficultyVisibility(@RequestBody @Valid IssueVisibilityVo issueVisibilityVo){
        return issueService.getDifficultyVisibility(issueVisibilityVo);
    }

    /**
     * 题库可视化不同难度下题目类型数量
     * @param issueVisibilityVo
     * @return
     */
    @PostMapping(value = "/getDifficultyTypeVisibility")
    public Response getDifficultyTypeVisibility(@RequestBody @Valid IssueVisibilityVo issueVisibilityVo){
        return issueService.getDifficultyTypeVisibility(issueVisibilityVo);
    }

    /**
     * 题库可视化题目类型引用次数
     * @param issueVisibilityVo
     * @return
     */
    @PostMapping(value = "/getTypeRefNumVisibility")
    public Response getTypeRefNumVisibility(@RequestBody @Valid IssueVisibilityVo issueVisibilityVo){
        return issueService.getTypeRefNumVisibility(issueVisibilityVo);
    }

    /**
     * 题库导入模板下载
     * @return
     */
    @RequestMapping(value = "/downloadExcelTemplate")
    public Response downloadExcelTemplate(){
        try{
            return FileUtil.downloadFileByWeb(EXCEL_MODEL,response);
        }catch (Exception e){
            return Response.error(ResultCode.FILE_DOWNLOAD_ERROR.getMsg(), ResultCode.FILE_DOWNLOAD_ERROR.getCode());
        }
    }

    @PostMapping(value = "/getSecondGameIssue")
    public Response getSecondGameIssue(@RequestBody Map<String,Integer> map){
        int courseId,type;
        try {
            courseId = map.get("courseId");
            type = map.get("type");
        }catch (Exception e){
            return Response.ok(ResultCode.PARAMETER_MISS);
        }
        return Response.ok(issueService.getSecondGameIssue(courseId,type));
    }
}

